package com.cencat.route.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cencat.route.entity.Dispatch;
import com.cencat.route.mapper.DispatchMapper;
import com.cencat.route.service.DispatchService;
import com.cencat.route.vo.DispatchQueryVO;
import com.cencat.route.vo.DispatchStatisticsVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;

/**
 * 调度服务实现类
 * 
 * @author cencat
 * @since 2024-01-01
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class DispatchServiceImpl extends ServiceImpl<DispatchMapper, Dispatch> implements DispatchService {

    private final DispatchMapper dispatchMapper;

    @Override
    public Page<Dispatch> selectDispatchPage(Page<Dispatch> page, DispatchQueryVO query) {
        return dispatchMapper.selectDispatchPage(page, query);
    }

    @Override
    public List<Dispatch> selectDispatchList(DispatchQueryVO query) {
        return dispatchMapper.selectDispatchList(query);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchUpdateDispatchStatus(List<Long> ids, String status, Long updatedBy) {
        try {
            return dispatchMapper.batchUpdateDispatchStatus(ids, status, updatedBy) > 0;
        } catch (Exception e) {
            log.error("批量更新调度状态失败: {}", e.getMessage(), e);
            throw new RuntimeException("批量更新调度状态失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchUpdatePriority(List<Long> ids, Integer priority, Long updatedBy) {
        try {
            return dispatchMapper.batchUpdatePriority(ids, priority, updatedBy) > 0;
        } catch (Exception e) {
            log.error("批量更新调度优先级失败: {}", e.getMessage(), e);
            throw new RuntimeException("批量更新调度优先级失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchAssignDriver(List<Long> ids, Long driverId, Long assignedBy) {
        try {
            return dispatchMapper.batchAssignDriver(ids, driverId, assignedBy) > 0;
        } catch (Exception e) {
            log.error("批量分配司机失败: {}", e.getMessage(), e);
            throw new RuntimeException("批量分配司机失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchAssignVehicle(List<Long> ids, Long vehicleId, Long assignedBy) {
        try {
            return dispatchMapper.batchAssignVehicle(ids, vehicleId, assignedBy) > 0;
        } catch (Exception e) {
            log.error("批量分配车辆失败: {}", e.getMessage(), e);
            throw new RuntimeException("批量分配车辆失败", e);
        }
    }

    @Override
    public DispatchStatisticsVO getDispatchStatistics() {
        try {
            return dispatchMapper.getDispatchStatistics();
        } catch (Exception e) {
            log.error("获取调度统计信息失败: {}", e.getMessage(), e);
            throw new RuntimeException("获取调度统计信息失败", e);
        }
    }

    @Override
    public String intelligentMatchDispatch(String requirements) {
        try {
            return dispatchMapper.intelligentMatchDispatch(requirements);
        } catch (Exception e) {
            log.error("智能匹配调度失败: {}", e.getMessage(), e);
            throw new RuntimeException("智能匹配调度失败", e);
        }
    }

    @Override
    public List<Dispatch> getUrgentDispatches(Integer limit) {
        try {
            return dispatchMapper.getUrgentDispatches(limit);
        } catch (Exception e) {
            log.error("获取紧急调度列表失败: {}", e.getMessage(), e);
            throw new RuntimeException("获取紧急调度列表失败", e);
        }
    }

    @Override
    public List<Dispatch> getPendingDispatches(Integer limit) {
        try {
            return dispatchMapper.getPendingDispatches(limit);
        } catch (Exception e) {
            log.error("获取待处理调度列表失败: {}", e.getMessage(), e);
            throw new RuntimeException("获取待处理调度列表失败", e);
        }
    }

    @Override
    public List<Dispatch> getActiveDispatches(Integer limit) {
        try {
            return dispatchMapper.getActiveDispatches(limit);
        } catch (Exception e) {
            log.error("获取活跃调度列表失败: {}", e.getMessage(), e);
            throw new RuntimeException("获取活跃调度列表失败", e);
        }
    }

    @Override
    public List<Dispatch> getCompletedDispatches(Integer limit) {
        try {
            return dispatchMapper.getCompletedDispatches(limit);
        } catch (Exception e) {
            log.error("获取已完成调度列表失败: {}", e.getMessage(), e);
            throw new RuntimeException("获取已完成调度列表失败", e);
        }
    }

    @Override
    public List<Dispatch> getHighPriorityDispatches(Integer minPriority, Integer limit) {
        try {
            return dispatchMapper.getHighPriorityDispatches(minPriority, limit);
        } catch (Exception e) {
            log.error("获取高优先级调度列表失败: {}", e.getMessage(), e);
            throw new RuntimeException("获取高优先级调度列表失败", e);
        }
    }

    @Override
    public List<Dispatch> getNewCreatedDispatches(Integer hours, Integer limit) {
        try {
            return dispatchMapper.getNewCreatedDispatches(hours, limit);
        } catch (Exception e) {
            log.error("获取新创建调度列表失败: {}", e.getMessage(), e);
            throw new RuntimeException("获取新创建调度列表失败", e);
        }
    }

    @Override
    public boolean checkDispatchExists(Long id) {
        try {
            return dispatchMapper.checkDispatchExists(id) > 0;
        } catch (Exception e) {
            log.error("检查调度是否存在失败: {}", e.getMessage(), e);
            return false;
        }
    }

    @Override
    public boolean checkDispatchCodeExists(String dispatchCode, Long excludeId) {
        try {
            return dispatchMapper.checkDispatchCodeExists(dispatchCode, excludeId) > 0;
        } catch (Exception e) {
            log.error("检查调度编码是否存在失败: {}", e.getMessage(), e);
            return false;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean createDispatch(Dispatch dispatch) {
        try {
            // 检查调度编码是否已存在
            if (checkDispatchCodeExists(dispatch.getDispatchCode(), null)) {
                throw new RuntimeException("调度编码已存在");
            }
            
            // 设置默认值
            dispatch.setStatus("PENDING");
            dispatch.setPriority(1);
            
            return save(dispatch);
        } catch (Exception e) {
            log.error("创建调度失败: {}", e.getMessage(), e);
            throw new RuntimeException("创建调度失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateDispatchInfo(Long dispatchId, String description, Integer priority, Long updatedBy) {
        try {
            return dispatchMapper.updateDispatchInfo(dispatchId, description, priority, updatedBy) > 0;
        } catch (Exception e) {
            log.error("更新调度信息失败: {}", e.getMessage(), e);
            throw new RuntimeException("更新调度信息失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean assignDispatch(Long dispatchId, Long driverId, Long vehicleId, Long assignedBy) {
        try {
            return dispatchMapper.assignDispatch(dispatchId, driverId, vehicleId, assignedBy) > 0;
        } catch (Exception e) {
            log.error("分配调度失败: {}", e.getMessage(), e);
            throw new RuntimeException("分配调度失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean startDispatch(Long dispatchId, Long startedBy) {
        try {
            return dispatchMapper.startDispatch(dispatchId, startedBy) > 0;
        } catch (Exception e) {
            log.error("开始调度失败: {}", e.getMessage(), e);
            throw new RuntimeException("开始调度失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean completeDispatch(Long dispatchId, String completionNotes, Long completedBy) {
        try {
            return dispatchMapper.completeDispatch(dispatchId, completionNotes, completedBy) > 0;
        } catch (Exception e) {
            log.error("完成调度失败: {}", e.getMessage(), e);
            throw new RuntimeException("完成调度失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean cancelDispatch(Long dispatchId, String cancelReason, Long cancelledBy) {
        try {
            return dispatchMapper.cancelDispatch(dispatchId, cancelReason, cancelledBy) > 0;
        } catch (Exception e) {
            log.error("取消调度失败: {}", e.getMessage(), e);
            throw new RuntimeException("取消调度失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean pauseDispatch(Long dispatchId, String pauseReason, Long pausedBy) {
        try {
            return dispatchMapper.pauseDispatch(dispatchId, pauseReason, pausedBy) > 0;
        } catch (Exception e) {
            log.error("暂停调度失败: {}", e.getMessage(), e);
            throw new RuntimeException("暂停调度失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean resumeDispatch(Long dispatchId, Long resumedBy) {
        try {
            return dispatchMapper.resumeDispatch(dispatchId, resumedBy) > 0;
        } catch (Exception e) {
            log.error("恢复调度失败: {}", e.getMessage(), e);
            throw new RuntimeException("恢复调度失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateDispatchProgress(Long dispatchId, Integer progress, String progressNotes, Long updatedBy) {
        try {
            return dispatchMapper.updateDispatchProgress(dispatchId, progress, progressNotes, updatedBy) > 0;
        } catch (Exception e) {
            log.error("更新调度进度失败: {}", e.getMessage(), e);
            throw new RuntimeException("更新调度进度失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateDispatchLocation(Long dispatchId, String currentLocation, BigDecimal latitude, BigDecimal longitude, Long updatedBy) {
        try {
            return dispatchMapper.updateDispatchLocation(dispatchId, currentLocation, latitude, longitude, updatedBy) > 0;
        } catch (Exception e) {
            log.error("更新调度位置失败: {}", e.getMessage(), e);
            throw new RuntimeException("更新调度位置失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateDispatchSchedule(Long dispatchId, String scheduledStartTime, String scheduledEndTime, Long updatedBy) {
        try {
            return dispatchMapper.updateDispatchSchedule(dispatchId, scheduledStartTime, scheduledEndTime, updatedBy) > 0;
        } catch (Exception e) {
            log.error("更新调度计划失败: {}", e.getMessage(), e);
            throw new RuntimeException("更新调度计划失败", e);
        }
    }

    @Override
    public String analyzeDispatchPerformance(Long dispatchId, String startDate, String endDate) {
        try {
            return dispatchMapper.analyzeDispatchPerformance(dispatchId, startDate, endDate);
        } catch (Exception e) {
            log.error("分析调度性能失败: {}", e.getMessage(), e);
            throw new RuntimeException("分析调度性能失败", e);
        }
    }

    @Override
    public String generateDispatchReport(Long dispatchId, String reportType) {
        try {
            return dispatchMapper.generateDispatchReport(dispatchId, reportType);
        } catch (Exception e) {
            log.error("生成调度报告失败: {}", e.getMessage(), e);
            throw new RuntimeException("生成调度报告失败", e);
        }
    }

    @Override
    public String exportDispatchData(DispatchQueryVO query, String exportFormat) {
        try {
            return dispatchMapper.exportDispatchData(query, exportFormat);
        } catch (Exception e) {
            log.error("导出调度数据失败: {}", e.getMessage(), e);
            throw new RuntimeException("导出调度数据失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String importDispatchData(String importData, Long importedBy) {
        try {
            return dispatchMapper.importDispatchData(importData, importedBy);
        } catch (Exception e) {
            log.error("导入调度数据失败: {}", e.getMessage(), e);
            throw new RuntimeException("导入调度数据失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchProcessDispatches(List<Long> dispatchIds, String processType, Long processedBy) {
        try {
            return dispatchMapper.batchProcessDispatches(dispatchIds, processType, processedBy) > 0;
        } catch (Exception e) {
            log.error("批量处理调度失败: {}", e.getMessage(), e);
            throw new RuntimeException("批量处理调度失败", e);
        }
    }

    @Override
    public String getDispatchRecommendations(Long dispatchId) {
        try {
            return dispatchMapper.getDispatchRecommendations(dispatchId);
        } catch (Exception e) {
            log.error("获取调度推荐失败: {}", e.getMessage(), e);
            throw new RuntimeException("获取调度推荐失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean recordDispatchEvent(Long dispatchId, String eventType, String eventDescription, Long recordedBy) {
        try {
            return dispatchMapper.recordDispatchEvent(dispatchId, eventType, eventDescription, recordedBy) > 0;
        } catch (Exception e) {
            log.error("记录调度事件失败: {}", e.getMessage(), e);
            throw new RuntimeException("记录调度事件失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateDispatchRating(Long dispatchId, BigDecimal rating, String feedback, Long ratedBy) {
        try {
            return dispatchMapper.updateDispatchRating(dispatchId, rating, feedback, ratedBy) > 0;
        } catch (Exception e) {
            log.error("更新调度评分失败: {}", e.getMessage(), e);
            throw new RuntimeException("更新调度评分失败", e);
        }
    }

    @Override
    public String getDispatchAlternatives(Long dispatchId, Integer maxAlternatives) {
        try {
            return dispatchMapper.getDispatchAlternatives(dispatchId, maxAlternatives);
        } catch (Exception e) {
            log.error("获取调度替代方案失败: {}", e.getMessage(), e);
            throw new RuntimeException("获取调度替代方案失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean optimizeDispatch(Long dispatchId, String optimizationType, Long optimizedBy) {
        try {
            return dispatchMapper.optimizeDispatch(dispatchId, optimizationType, optimizedBy) > 0;
        } catch (Exception e) {
            log.error("优化调度失败: {}", e.getMessage(), e);
            throw new RuntimeException("优化调度失败", e);
        }
    }

    @Override
    public String validateDispatch(Long dispatchId) {
        try {
            return dispatchMapper.validateDispatch(dispatchId);
        } catch (Exception e) {
            log.error("验证调度失败: {}", e.getMessage(), e);
            throw new RuntimeException("验证调度失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean archiveDispatch(Long dispatchId, String archiveReason, Long archivedBy) {
        try {
            return dispatchMapper.archiveDispatch(dispatchId, archiveReason, archivedBy) > 0;
        } catch (Exception e) {
            log.error("归档调度失败: {}", e.getMessage(), e);
            throw new RuntimeException("归档调度失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean restoreDispatch(Long dispatchId, Long restoredBy) {
        try {
            return dispatchMapper.restoreDispatch(dispatchId, restoredBy) > 0;
        } catch (Exception e) {
            log.error("恢复调度失败: {}", e.getMessage(), e);
            throw new RuntimeException("恢复调度失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean cloneDispatch(Long sourceDispatchId, String newDispatchCode, Long clonedBy) {
        try {
            return dispatchMapper.cloneDispatch(sourceDispatchId, newDispatchCode, clonedBy) > 0;
        } catch (Exception e) {
            log.error("克隆调度失败: {}", e.getMessage(), e);
            throw new RuntimeException("克隆调度失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean mergeDispatches(List<Long> dispatchIds, String newDispatchCode, Long mergedBy) {
        try {
            return dispatchMapper.mergeDispatches(dispatchIds, newDispatchCode, mergedBy) > 0;
        } catch (Exception e) {
            log.error("合并调度失败: {}", e.getMessage(), e);
            throw new RuntimeException("合并调度失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean splitDispatch(Long dispatchId, String splitConfig, Long splitBy) {
        try {
            return dispatchMapper.splitDispatch(dispatchId, splitConfig, splitBy) > 0;
        } catch (Exception e) {
            log.error("拆分调度失败: {}", e.getMessage(), e);
            throw new RuntimeException("拆分调度失败", e);
        }
    }

    @Override
    public String calculateDispatchCost(Long dispatchId) {
        try {
            return dispatchMapper.calculateDispatchCost(dispatchId);
        } catch (Exception e) {
            log.error("计算调度成本失败: {}", e.getMessage(), e);
            throw new RuntimeException("计算调度成本失败", e);
        }
    }

    @Override
    public Integer estimateDispatchTime(Long dispatchId) {
        try {
            return dispatchMapper.estimateDispatchTime(dispatchId);
        } catch (Exception e) {
            log.error("预估调度时间失败: {}", e.getMessage(), e);
            throw new RuntimeException("预估调度时间失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateDispatchStatistics(Long dispatchId, Long updatedBy) {
        try {
            return dispatchMapper.updateDispatchStatistics(dispatchId, updatedBy) > 0;
        } catch (Exception e) {
            log.error("更新调度统计信息失败: {}", e.getMessage(), e);
            throw new RuntimeException("更新调度统计信息失败", e);
        }
    }

    @Override
    public String getDispatchHistory(Long dispatchId) {
        try {
            return dispatchMapper.getDispatchHistory(dispatchId);
        } catch (Exception e) {
            log.error("获取调度历史失败: {}", e.getMessage(), e);
            throw new RuntimeException("获取调度历史失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean notifyDispatchUpdate(Long dispatchId, String notificationType, String message, Long notifiedBy) {
        try {
            return dispatchMapper.notifyDispatchUpdate(dispatchId, notificationType, message, notifiedBy) > 0;
        } catch (Exception e) {
            log.error("通知调度更新失败: {}", e.getMessage(), e);
            throw new RuntimeException("通知调度更新失败", e);
        }
    }

    @Override
    public String getDispatchMetrics(Long dispatchId, String metricsType) {
        try {
            return dispatchMapper.getDispatchMetrics(dispatchId, metricsType);
        } catch (Exception e) {
            log.error("获取调度指标失败: {}", e.getMessage(), e);
            throw new RuntimeException("获取调度指标失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean escalateDispatch(Long dispatchId, String escalationReason, Long escalatedBy) {
        try {
            return dispatchMapper.escalateDispatch(dispatchId, escalationReason, escalatedBy) > 0;
        } catch (Exception e) {
            log.error("升级调度失败: {}", e.getMessage(), e);
            throw new RuntimeException("升级调度失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deescalateDispatch(Long dispatchId, String deescalationReason, Long deescalatedBy) {
        try {
            return dispatchMapper.deescalateDispatch(dispatchId, deescalationReason, deescalatedBy) > 0;
        } catch (Exception e) {
            log.error("降级调度失败: {}", e.getMessage(), e);
            throw new RuntimeException("降级调度失败", e);
        }
    }

}